/*
Some helper functions
*/

var trimWhiteSpaceCharsRegexp = new RegExp('[\\s]', 'g');

function myTrim(str)	{
	return str.replace( trimWhiteSpaceCharsRegexp, '' );
}

function addEvent(obj, evType, fn, bubble)	{
	if (obj.addEventListener){
		obj.addEventListener(evType, fn, bubble);
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent('on'+evType, fn);
		return r;
	} else {
		return false;
	}
}

function openCloseObject(objId)	{			
	var obj = document.getElementById(objId);	
	if (obj.style.display == 'none') 	{
		obj.style.display = 'block';
		return;
	}	
	if (obj.style.display == 'block') 	{
		obj.style.display = 'none';
	}	
}

function showHideObject(objId)	{	
	var obj = document.getElementById(objId);	
	if ( 'undefined' != obj && null != obj ) 	{
		if ( 'hidden' == obj.style.visibility )	{			
			obj.style.visibility = 'visible';
		}
		else	{
			obj.style.visibility = 'hidden';
		}
	}	
}

function createMultiArray(rowNum, colNum)	{
	var res = new Array(rowNum);
	var i = 0;
	for ( i = 0; i < rowNum; i++ )	{
		res[i] = new Array(colNum);
	}
	return res;
}

// Maybe not working, can't find a way to set the idx value in the array.sort(fn) method
function sortMultidimensionalArray(a, b, idx, caseInSensitive)    {
    if ( idx == null || idx == 'undefined' )    {
        idx = 0;
    }
    return caseInSensitive 
    ? ( ( a[idx].toUpperCase() < b[idx].toUpperCase() ) ? -1 : 1 )
    : ( ( a[idx] < b[idx] ) ? -1 : 1 );
}

function sortMultidimensionalArrayBySecondVal(a, b, caseInSensitive )    {    
    return sortMultidimensionalArray(a, b, 1, ( caseInSensitive != 'undefined' && caseInSensitive != null && caseInSensitive ) );
}

function sortMultidimensionalArrayBySecondValInCaseSensitiveMode(a, b)    {    
    return sortMultidimensionalArrayBySecondVal(a, b, true );
}

function getElementFromListByName( elementList, elementName )	{
	if ( ( elementList == null || elementList == 'undefined' ) && ( elementName == null || elementName == 'undefined' ) ) 	{
		return null;
	}	
	var elementListIterator = 0;
	for ( elementListIterator = 0; elementListIterator < elementList.length; elementListIterator++ )	{
		if ( elementList[elementListIterator].className == elementName )	{
			return elementList[elementListIterator];
		}		
	}
	
	return null;
}

function getNodeFirstChildByClassName( node, childNodeClassName )	{
	if ( ( node == null || node == 'undefined' ) && ( childNodeClassName == null || childNodeClassName == 'undefined' ) )	{
		return null;
	}	
	var nodeChildIterator = 0;
	for ( nodeChildIterator = 0; nodeChildIterator < node.childNodes.length; nodeChildIterator++ )	{
		if ( node.childNodes[nodeChildIterator].className == childNodeClassName )	{
			return node.childNodes[nodeChildIterator];
		}		
	}
	return null;
}

function getNodeFirstChildByName(node, childName, recursive )	{	
	if ( ( node == null || node == 'undefined' ) && ( childName == null || childName == 'undefined' ) ) 	{		
		return null;
	}	
	var res = null;
	var nodeChildIterator = 0;
	for ( nodeChildIterator = 0; nodeChildIterator < node.childNodes.length; nodeChildIterator++ )	{				
		if ( node.childNodes[nodeChildIterator].nodeName == childName )	{
			res = node.childNodes[nodeChildIterator];
		}		
		if ( recursive && node.childNodes[nodeChildIterator].childNodes.length > 0 ) {
			res = getNodeFirstChildByName(node.childNodes[nodeChildIterator], childName, recursive);
		}
		if ( res != null )	{
			return res;
		}
	}
	return null;
}

function getNodeText( node, recursive )	{
	var textChildNode = getNodeFirstChildByName( node, '#text', recursive );
	if ( textChildNode == null || textChildNode == 'undefined' )	{
		return '';
	}
	return textChildNode.nodeValue;
}

// Working buggy, debug before use
function setNodeText(node, newNodeText, recursive )	{
	var oldNodeText = getNodeText( node, '#text', recursive );
	if ( null != oldNodeText && undefined != oldNodeText )	{		
		oldNodeText.nodeValue = newNodeText;
	}
}

function getTextNode( node, recursive ){
	var textChildNode = getNodeFirstChildByName( node, '#text', recursive );
	if ( textChildNode == null || textChildNode == 'undefined' )	{
		return '';
	}
	return textChildNode;
}

function getPreviousSibling(node)	{
	if ( node == null || node == 'undefined' ) 	{
		return null;
	}
	mother = node.parentNode;
	if ( mother == null || mother == 'undefined' || mother.childNodes[0] === node ) 	{
		return null;	// it can only occurs when processing root elements or this is the first node
	}
	var childNodeIterator = 0;
	for ( childNodeIterator = 0; childNodeIterator < mother.childNodes.length; childNodeIterator++ )	{
		if ( mother.childNodes[childNodeIterator] == node ) {
			return mother.childNodes[childNodeIterator - 1 ] ;
		}
	}
	return null;
}

function containsKey( inputMap, lookup ) {
	if ( ( inputMap == 'undefined' || inputMap == null ) && ( lookup == 'undefined' || lookup == null ) ) {  
    return false;
  }
  for (var key in inputMap ) {
    if ( key == lookup ) {
      return true;
    }
  }
  return false;
}

function containsValue( inputMap, lookup ) {
  if ( ( inputMap == 'undefined' || inputMap == null ) && ( lookup == 'undefined' || lookup == null ) ) {
    return false;
  }
  for (var key in inputMap ) {
    if ( inputMap[key] == lookup ) {
      return true;
    }
  }
  return false;
}

function getKeyByValue( inputMap, lookup ) {
  if ( ( inputMap == 'undefined' || inputMap == null ) && ( lookup == 'undefined' || lookup == null ) ) {
    return null;
  }
  for (var key in inputMap ) {
    if ( inputMap[key] == lookup ) {
      return key;
    }
  }
  return null;
}

function convertMapToArray(inputMap) {
  if ( inputMap == 'undefined' || inputMap == null ) {
    return null;
  }
  var res = new Array();
  var i = 0;
  for (var key in inputMap ) {
  	res[i] = new Array(2);
  	res[i][0] = key;
    res[i][1] = inputMap[key];
    i++;
  }
  return res;
}

function convertArrayToMap(inputArray)	{
	// inputArray form should be : [[key1,val1],[key2,val2],[key3,val3]]
	var res = new Object(); 
	if ( inputArray == 'undefined' || inputArray == null ) {
		return null;
	}
	var c = inputArray.length;
	var i = 0;
	var key = null;
	var value = null;
	for ( i = 0; i != c; i++ )	{
		key = inputArray[i][0];
		value = inputArray[i][1];
		res[ key ] = value; 
	}
	return res;
  
}

function convertStringToMap(inputString)	{
	if ( inputString == 'undefined' || inputString == null )	{
		return null;
	}		
	// inputString should be like : {key1=val1||key2=val2}
	var res = new Object();
	var onePair = null;
	var idx = 0;
	var keyValuePairs = inputString.replace(/[{}]/g, '').split('||');	
	for ( idx in keyValuePairs )	{
		onePair = keyValuePairs[idx].split('=');		
		res[onePair[0]] = onePair[1];
	}
	return res;
}

function convertMapToString( inputMap )	{
	if ( inputMap == 'undefined' || inputMap == null )	{
		return null;
	}
	var res = '';
	var key = null;
	for ( key in inputMap ) {
		res += '||' + key + '=' + inputMap[key];
	}	
	res = res.replace(/\|*/, '{' );
	res += '}';
	return res;
}

function removeFromMap( inputMap, removeKey )	{
	return delete inputMap[removeKey];
}

function convertBooleanToDivDisplayValue( val )	{
	return val ? 'block' : 'none';
}

function convertDivDisplayValueToBoolean( val )	{
	return 'block' == val ;
}

function getValueIndexFromArray(lookupArray, lookupValue)	{
	var idx = -1;
	var i = 0;
	while ( idx < 0 && i != lookupArray.length )	{		
		idx = lookupArray[i++] == lookupValue ? --i : -1;		
	}	
	return idx;
}

function convertSelectOptionsToArray(selectElement)	{
	var res = new Array();
	var i = 0;
	for ( i = 0; i != selectElement.length; i++ )	{
		res.push( selectElement.options[i].value );
	}
	return res;
}

function createButtonLikeCell(buttonText)	{
	var tableCellForButton = document.createElement('td');	
	tableCellForButton.innerHTML = buttonText;
	tableCellForButton.className = 'button';
	tableCellForButton.style.textAlign = 'center';		
	tableCellForButton.style.verticalAlign = 'middle';
	return tableCellForButton;
}

function createInputElement(elementType, elementId, elementValue, elementClass)	{
	return createInputElementWithName(elementType, elementId, elementValue, elementClass, null);
}
function createInputElementWithName(elementType, elementId, elementValue, elementClass, elementName)	{	
	if ( 'undefined' == elementType || null == elementType )	{
		return null;
	}	
	
	if ( 'select' == elementType )	{
		return createSelectElement(elementType, elementId, elementValue, elementClass);
	}
	var res = document.createElement('input');	
	res.type = elementType;
	
	res.id = ( 'undefined' == elementId || null == elementId ) ? '' : elementId;
	res.className =  ( 'undefined' == elementClass || null == elementClass ) ? '' : elementClass;
	
	if ( 'undefined' != elementValue && null != elementValue )	{
		res.value = elementValue;
	}
	
	if ( 'undefined' != elementName && null != elementName )	{
		res.name = elementName;
	}
	
	return res;
}



function createSelectElement(elementType, elementId, elementValue, elementClass)	{
	if ( 'undefined' == elementType || null == elementType || 'undefined' == elementId || null == elementId )	{
		return null;
	}		
	var optionVectorName = elementId.replace(/_ID/, '');
	var res = document.createElement('select');
	var optionVector = selectVectorValue[optionVectorName];
	var idx;
	for ( idx in optionVector )	{
		
		var newOption = document.createElement('option');
		newOption.value = idx;
		newOption.text = optionVector[idx];
		
		try	{
			res.add(newOption,null); // standards compliant
		}
		catch(ex)	{
			res.add(newOption); // IE only
		}
	}
	
	res.id = elementId;
	res.className =  ( 'undefined' == elementClass || null == elementClass ) ? '' : elementClass;
	
	if ( 'undefined' != elementValue && null != elementValue )	{
		res.selected = getValueIndexFromArray(res.options, elementValue);
	}
	return res;
}



function createHiddenDiv( divId, divContent )	{
	var hiddenDiv = document.createElement('div');
	hiddenDiv.style.display = 'none';
	hiddenDiv.style.visibility = 'hidden';
	hiddenDiv.id = 'undefined' == divId || null == divId ? 'hiddenDiv' + ( Math.random() * 100 ) : divId ;
	
	if (divContent)	{
		hiddenDiv.innerHTML = 'string' == typeof divContent ? divContent : divContent.toXMLString();
	}	
	
	return hiddenDiv;
}

function createPaddingRow( nrOfCells, isColspan )	{
	var paddingTableRow = document.createElement('tr');
	var i = 0;
	if ( isColspan )	{
		paddingTableRow.appendChild( createPaddingCell( nrOfCells ) );
		return paddingTableRow;
	}
	for ( i = 0; i != nrOfCells; i++ )	{
		paddingTableRow.appendChild( createPaddingCell(0) );
	}		
	return paddingTableRow;
}

function createPaddingCell( nrOfColSpan )	{	
	var paddingTableCell = document.createElement('td');
	paddingTableCell.style.padding = '5px';	
	if ( nrOfColSpan > 1 )	{
		paddingTableCell.setAttribute('colspan', nrOfColSpan );
	}
	return paddingTableCell;
}


function cloneElement(type, className, styles, content) {	
  var res = document.createElement(type||"div");
  if (className) res.className = className;
  if (styles)
    for (var prop in styles)
      res.style[prop] = styles[prop];
  if (content)
    res.innerHTML = "string" == typeof content ? content : content.toXMLString();
  return res;
}


function getUserSettingValue( userSettingName, defaultValue )	{		
	//GM_deleteValue('messageTypesBox');	
	var settingValue = GM_getValue( userSettingName );
	if ( ( settingValue == 'undefined' || settingValue == null ) && defaultValue != 'undefined' && defaultValue != null )	{
		settingValue = defaultValue;
		saveUserSettingValue( userSettingName, settingValue );
	}
	return settingValue;
}

function saveUserSettingValue( userSettingName, actualValue )	{
	GM_setValue( userSettingName, actualValue );		
}

function savePlayerAllyDetails(page)	{	
	var hiddenDiv = document.createElement("div");
	hiddenDiv.innerHTML = page;	
	var playerAllyTd = $X(".//*[@class='table01']/tbody/tr[@class='alt own' or @class='own']/td[@class='allytag']", hiddenDiv );
	var playerAllyLink = $X("./a", playerAllyTd );
	var stringAfterAllyId = playerAllyLink.href.split('&allyId=')[1];
	var allyIdString = stringAfterAllyId.split('&')[0];	
	var allyName = allyIdString == 0 
		? 'N/A' 
		: playerAllyLink.innerHTML;		
	var strTosave = allyIdString + '=' + allyName;
	saveUserSettingValue('PLAYER_ALLY_DETAILS', strTosave );		
	PLAYER_ALLY_DETAILS = strTosave;
}

function requestPlayerDetails(playerName, fn) {
    GM_xmlhttpRequest({
        method:'POST',
        url:'http://' + gameServer + '/index.php',
        data:"view=highscore&highscoreType=score&searchUser=" + playerName,
        headers: {
            'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'application/atom+xml,application/xml,text/xml',
            'Referer': 'http://' + gameServer + '/index.php', 
            'Cookie': document.cookie
        },
        onload:fn
    } );
}

function requestMyDetails(fn)	{
	GM_xmlhttpRequest({
        method:'POST',
        url:'http://' + gameServer + '/index.php',        
//        data:'view=highscore&highscoreType=score&searchUser=salomone',
        data:'view=highscore&showMe=1',
        headers: {
            'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
            'Content-type': 'application/x-www-form-urlencoded',
            'Accept': 'application/atom+xml,application/xml,text/xml',
            'Referer': 'http://' + gameServer + '/index.php', 
            'Cookie': document.cookie
        },
        onload:fn
    } );
}

function dummyRequest(urlStr, dataStr) {
	  GM_xmlhttpRequest({
		  	method: 'POST',
		  	url: urlStr,
		  	data: dataStr,
		  	headers: {
		  		'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
		  		'Content-type': 'application/x-www-form-urlencoded',
		  		'Accept': 'application/atom+xml,application/xml,text/xml',
		  		'Referer': 'http://' + gameServer + '/index.php', 
		  		'Cookie': document.cookie
		  	},
		     onload: function(xhr) {}
		  });
		}

function getMessagePages(dataStr, fn) {
  GM_xmlhttpRequest({
  	method: 'POST',
  	url:'http://' + gameServer + '/index.php',
  	data: dataStr,
  	headers: {
  		'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
  		'Content-type': 'application/x-www-form-urlencoded',
  		'Accept': 'application/atom+xml,application/xml,text/xml',
  		'Referer': 'http://' + gameServer + '/index.php', 
  		'Cookie': document.cookie
  	},
     onload: function(xhr) { fn(xhr.responseText); }
  });
}


function $x( xpath, root ) {
  var doc = root ? root.evaluate ? root : root.ownerDocument : document, next;
  var got = doc.evaluate( xpath, root||doc, null, 0, null ), result = [];
  switch (got.resultType) {
    case got.STRING_TYPE:
      return got.stringValue;
    case got.NUMBER_TYPE:
      return got.numberValue;
    case got.BOOLEAN_TYPE:
      return got.booleanValue;
    default:
      while (next = got.iterateNext())
        result.push( next );
      return result;
  }
}

function $X( xpath, root ) {
  var got = $x( xpath, root );
  return got instanceof Array ? got[0] : got;
}

function getAddressBookList()	{
	var userListString = getUserSettingValue( 'ADDRESS_BOOKS', '' );
	if ( userListString == 'undefined' || userListString == null || userListString.length == 0 )	{
		return new Object();
	}
	var usedServer = '';
	var userListVector = userListString.split('###');		
	for ( userList in userListVector )	{				
		usedServer = userListVector[userList].split('##')[0];
		if ( usedServer == gameServer )	{
			return convertStringToMap( userListVector[userList].split('##')[1] );
		}
	}
	return null;
}

//	server0##{keyword00=option00;picture00path||keyword01=option01;picture01path}###server1##{keyword10=option10;picture10path||keyword11=option11;picture11path}
function getUserDefinedIconsAndMenuOptions()	{
	var userDefinedKeyword = getUserSettingValue( 'USER_DEFINED_KEYWORDS', '' );
	if ( userDefinedKeyword == 'undefined' || userDefinedKeyword == null || userDefinedKeyword.length == 0 )	{
		return null;
	}
	
	var menuOptionsPathMap = new Object();
	var iconPathMap = new Object();
	
	var res = null;
	var usedServer = '';
	var i = 0;
	var userDefinedKeywordVector = userDefinedKeyword.split('###');
	var pairedData = null;
	var j = 0;
	var keyWord = null;
	var menuOption = null;
	var iconPath = null;
	for ( i in userDefinedKeywordVector )	{				
		usedServer = userDefinedKeywordVector[i].split('##')[0];
		if ( usedServer == gameServer )	{
			pairedData = userDefinedKeywordVector[i].split('##')[1].replace(/[{}]/g, '').split('||');
			for ( j in pairedData )	{
				keyWord = pairedData[j].split('=')[0];
				menuOption = pairedData[j].split('=')[1].split(';')[0];
				iconPath = pairedData[j].split('=')[1].split(';')[1];
				iconPathMap[keyWord] = iconPath;
				menuOptionsPathMap[keyWord] = menuOption;		
			}
			continue;
		}
	}
	
	res = new Array(2);
	res[0] = menuOptionsPathMap;
	res[1] = iconPathMap;
	return res;
}

function saveAddressBookList( addressDetailsMap )	{
	actualAddressListString = convertMapToString( addressDetailsMap );			
	if ( actualAddressListString == 'undefined' || actualAddressListString == null )	{
		// No address book, nothing to do
		return;
	}
	var oldUserListString = getUserSettingValue( 'ADDRESS_BOOKS' );	
	if ( oldUserListString == 'undefined' || oldUserListString == null )	{
		oldUserListString = '';
	}
	var newUserListString = '';
	var usedServer = '';
	var userListVector = oldUserListString.split('###');
	for ( userList in userListVector )	{
		usedServer = userListVector[userList].split('##')[0];
		if ( usedServer != null && usedServer != '' && usedServer != gameServer )	{
			newUserListString += '##' + userListVector[userList];
		}
	}	
	actualAddressListString = gameServer + '##' + actualAddressListString;
	newUserListString = 
		newUserListString == '' 
		? actualAddressListString
		: actualAddressListString + newUserListString;
	saveUserSettingValue('ADDRESS_BOOKS', newUserListString );
}

//	s4.ikariam.hu##{keyword00=option00;/favicon.ico||keyword01=option01;picture01path}###server1##{keyword10=option10;picture10path||keyword11=option11;picture11path}
function saveUserDefinedKeywordsToFF( userDefinedMenuOptions, userDefinedPicturePaths )	{
	var keyword = '';
	var saveStr = '';
	for ( keyword in userDefinedMenuOptions )		{		
		saveStr += '||' + keyword + '=' + userDefinedMenuOptions[keyword] + ';' + userDefinedPicturePaths[keyword];
	}
	
	var append = true;
	if ( saveStr == '' )	{
		append = false;
	}
	else	{
		saveStr = saveStr.replace(/\|\|/, '');
		saveStr = gameServer + '##{' + saveStr + '}';
	}
	
	var userDefinedKeyword = getUserSettingValue( 'USER_DEFINED_KEYWORDS', '' );
	if ( userDefinedKeyword == 'undefined' || userDefinedKeyword == null || userDefinedKeyword.length == 0 )	{
		saveUserSettingValue('USER_DEFINED_KEYWORDS', saveStr );
		return;
	}	
	
	var usedServer = '';
	var i = 0;
	var userDefinedKeywordVector = userDefinedKeyword.split('###');
	for ( i in userDefinedKeywordVector )	{				
		usedServer = userDefinedKeywordVector[i].split('##')[0];
		if ( usedServer != gameServer )	{
			saveStr += '###' + 	userDefinedKeywordVector[i];
		}
	}
	
	if ( !append )	{
		saveStr = saveStr.replace(/###/, '');
	}
	
	saveUserSettingValue('USER_DEFINED_KEYWORDS', saveStr );
	return;
	
}


function dummy()	{
	return true;
}
/*
function waitForMilliSecconds(delayTimeInMilliSeconds){
	// www.sean.co.uk // Thx for the code
	var date = new Date();
	var curDate = null;
	
	do {
		curDate = new Date();
	}
	while (curDate - date < delayTimeInMilliSeconds);
}
*/
function createSubjectPicture(imgSource){
    if (imgSource == null) {
        return null;
    }
    res = document.createElement('img');
    res.width = '15';
    res.height = '15';
    res.src = imgSource;
    
    return res;
}


function formatDateCell( tableRow )	{	
	var dateCell = $X("./td[last()]", tableRow );
	dateCell.innerHTML = getFormattedDate( dateCell.innerHTML );
	return tableRow;
}

function getFormattedDate( oldDate )	{
	var day = oldDate.split(' ')[0].split('.');
	var time = oldDate.split(' ')[1].split(':');
	
	if ( day.length != 3 && time.length < 2 )	{
		return oldDate;
	}
	
	var d = new Date(
		parseInt(day[2].replace(/^[0]/g,"")),
		parseInt(day[1].replace(/^[0]/g,"")) - 1,
		parseInt(day[0].replace(/^[0]/g,"")),
		parseInt(time[0]),
		parseInt(time[1].replace(/^[0]/g,"")),
		time.length == 3 ? parseInt(time[2].replace(/^[0]/g,"")) : 0,
	0
	);	
	return d.toLocaleString();
}

function getPictureSrc( linkName )	{
	var pictureLink = defaultSubjectIcons[linkName];					
	if ( ( pictureLink == null || pictureLink == undefined ) && userDefinedPicturePaths != null )	{
		pictureLink = userDefinedPicturePaths[linkName];
	}
	if ( pictureLink != null && pictureLink != undefined )	{
		if ( pictureLink == ENCODED_IMAGE_TYPE )	{
			pictureLink = encodedImages[myTrim(linkName)];
		}														
		return pictureLink;
	}
	return null;
}